package com.mind.core.net.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;

import org.apache.log4j.Logger;

import com.mind.core.net.model.IConnector;
import com.mind.core.net.msg.Message;
import com.mind.core.net.msg.MessageType;
import com.mind.core.net.msg.PolicyMessage;
import com.mind.core.net.msg.sys.SessionMessage;
import com.mind.core.net.processor.IMessageProcessor;

/**
 * 
 * 从Socket接收到的消息处理器,处理以下操作:
 * 
 * <pre>
 * 1.新连接 向MessageProcess队列中增加一个状态为SESSION_OPENED的SessionMessage消息,由IMessageHandler处理新连接的逻辑
 * 2.收到消息 只处理类型为ISenderMessage的消息,将收到的消息增加到MessageProcessor队列中
 * 3.连接断开 向MessageProcess队列中增加一个SESSION_CLOSED的SessionMessage消息,由IMessageHandler处理连接断开的逻辑
 * </pre>
 * 
 * @
 * 
 * 
 */

public abstract class AbstractIoClientHandler<T extends IConnector> extends SimpleChannelInboundHandler {
	private static final Logger logger = org.apache.log4j.Logger
			.getLogger(AbstractIoClientHandler.class);
	protected final IMessageProcessor msgProcessor;
	private static final AttributeKey<IConnector> PLAYER =AttributeKey.valueOf("socket");

	public AbstractIoClientHandler(IMessageProcessor processor) {
		this.msgProcessor = processor;
	}
	/**
	 * 处理流程:
	 * 
	 * <pre>
	 * 1.为新连接创建一个Sender实例,并将Sender与session绑定
	 * 2.创建一个系统消息SessionMessage实例,将其放入MessageProcessor的消息队列中等待处理
	 * </pre>
	 * 
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) {
		Message msg = new SessionMessage(SessionMessage.SESSION_OPENED);
		IConnector basePlayer = this.createSender();
		basePlayer.setChannel(ctx.channel());
		msg.setSender(basePlayer);
		msgProcessor.put(msg);
		ctx.channel().attr(PLAYER).set(basePlayer);
		System.out.println("----------------------------------------------------------");
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		logger.info("", cause);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		IConnector player = ctx.channel().attr(PLAYER).get();
		if (player != null) {
			player.setChannel(null);
		}
		System.out.println("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||");
	}

	/**
	 * 由子类实现的
	 * 
	 * @return
	 */
	protected abstract IConnector createSender();

	@Override
	protected void messageReceived(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		if (!(msg instanceof Message)) {
			return;
		}
		IConnector player = ctx.channel().attr(PLAYER).get();
		if (player != null) {
			Message base = (Message) msg;
			base.setSender(player);
			if (base.getMessageType() == MessageType.FLASH_POLICY) {
				// 特殊的处理,响应Flash socket policy请求
				PolicyMessage _pm = (PolicyMessage) msg;
				_pm.initPolicy();
				ctx.channel().writeAndFlush(msg);
				return;
			}
			msgProcessor.put(base);
		}
	}
}
